﻿using Manon.Admin.Web.Application.Dtos.News;
using Manon.Admin.Web.Domain.Entities;
using Manon.Admin.Web.Domain.Repositories;
using Manon.Core;
using Manon.Core.Commons;
using Manon.Core.Extensions;
using Manon.Repository;
using Manon.Repository.Collections;
using Microsoft.EntityFrameworkCore;

namespace Manon.Admin.Web.Application.Impl
{
    public class NewsService : INewsService
    {
        private readonly ILogger<NewsService> _logger;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IApplicationUser _applicationUser;

        private readonly INewsRepository _newsRepository;
        private readonly INewsCategoryRepository _newsCategoryRepository;

        public NewsService(INewsRepository newsRepository,
            INewsCategoryRepository newsCategoryRepository,
            IUnitOfWork unitOfWork,
            IApplicationUser applicationUser,
            ILogger<NewsService> logger
            )
        {
            _newsRepository = newsRepository;
            _newsCategoryRepository = newsCategoryRepository;
            _unitOfWork = unitOfWork;
            _applicationUser = applicationUser;
            _logger = logger;
        }

        #region 资讯分类
        public async Task<NewsCategoryOutput> GetNewsCategory(int categoryId)
        {
            if (categoryId <= 0) return new NewsCategoryOutput() { Enabled = true };

            try
            {
                var result = await _newsCategoryRepository.GetFirstOrDefaultAsync(x => x.Id == categoryId);
                return result.ConvertTo<NewsCategory, NewsCategoryOutput>();
            }
            catch (Exception ex)
            {
                _logger.LogError("获取资讯分类异常", ex);
                throw;
            }
        }

        public async Task<List<NewsCategoryOutput>> GetNewsCateogryList()
        {
            try
            {
                var result = await _newsCategoryRepository.GetQuery().OrderBy(m => m.OrderIndex).ToListAsync();

                return result.ConvertTo<NewsCategory, NewsCategoryOutput>();

            }
            catch (Exception ex)
            {
                _logger.LogError("获取资讯分类异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 保存资讯分类
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SaveNewsCategory(NewsCategoryInput Input)
        {
            try
            {
                var result = await _newsCategoryRepository.GetFirstOrDefaultAsync(x => x.Id == Input.Id);
                if (result == null)
                {
                    result = new NewsCategory();
                    result.CategoryName = Input.CategoryName;
                    result.CreateTime = DateTime.Now;
                    result.Enabled = Input.Enabled;
                    result.UpdateTime = DateTime.Now;
                    result.OrderIndex = Input.OrderIndex;
                    result.CreateBy = _applicationUser.UserId;
                    result.UpdateBy = _applicationUser.UserId;
                    await _newsCategoryRepository.InsertAsync(result);
                }
                else
                {
                    result.CategoryName = Input.CategoryName;
                    result.Enabled = Input.Enabled;
                    result.UpdateTime = DateTime.Now;
                    result.OrderIndex = Input.OrderIndex;
                    result.UpdateBy = _applicationUser.UserId;
                    await _newsCategoryRepository.UpdateAsync(result);
                }
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("保存成功!");
            }
            catch (Exception ex)
            {
                _logger.LogError("保存资讯分类异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 设置资讯分类是否可用
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SetNewsCategoryEnabled(int categoryId, bool enabled)
        {
            try
            {

                var newsCategory = await _newsCategoryRepository.GetFirstOrDefaultAsync(x => x.Id == categoryId);
                if (newsCategory == null) return null;
                newsCategory.Enabled = enabled;
                await _newsCategoryRepository.UpdateAsync(newsCategory);
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("设置成功!");

            }
            catch (Exception ex)
            {
                _logger.LogError("设置资讯分类是否可用异常", ex);
                throw;
            }
        }

        #endregion

        #region 资讯
        /// <summary>
        /// 获取资讯
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<NewsOutput> GetNews(int id)
        {
            if (id <= 0) return new NewsOutput() { Enabled = true };

            try
            {
                var result = await _newsRepository.GetFirstOrDefaultAsync(x => x.Id == id);

                return result.ConvertTo<News, NewsOutput>();
            }
            catch (Exception ex)
            {
                _logger.LogError("获取资讯异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 获取资讯列表
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<PagedList<NewsOutput>> GetNewsPagedList(GetNewsPagedListInput Input)
        {
            try
            {
                var categorys = await _newsCategoryRepository.GetListAsync();

                var result = await _newsRepository
                    .GetQuery()
                    .WhereIf(!string.IsNullOrEmpty(Input.Keyword), e => e.Title.Contains(Input.Keyword) || e.Keyword.Contains(Input.Keyword) || e.Source.Contains(Input.Keyword) || e.Author.Contains(Input.Keyword))
                    .WhereIf(Input.Enabled.HasValue, e => e.Enabled == Input.Enabled.Value)
                    .WhereIf(Input.CategoryId > 0, e => e.CategoryId == Input.CategoryId)
                    .ToPagedListAsync(Input);

                PagedList<NewsOutput> pageResult = result.ConvertTo<PagedList<News>, PagedList<NewsOutput>>();
                if (pageResult != null && pageResult.Items != null)
                {
                    foreach (var item in pageResult.Items)
                    {
                        string categoryName = categorys?.Where(n => n.Id == item.CategoryId).FirstOrDefault()?.CategoryName; ;
                        item.CategoryName = categoryName;
                    }
                }
                return pageResult;
            }
            catch (Exception ex)
            {
                _logger.LogError("获取资讯列表异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 保存资讯 
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SaveNews(NewsInput Input)
        {
            try
            {
                var result = await _newsRepository.GetFirstOrDefaultAsync(x => x.Id == Input.Id);
                if (result == null)
                {
                    result = new News();
                    result.AllowComment = Input.AllowComment;
                    result.ArticleAbstract = Input.ArticleAbstract;
                    result.ArticleContent = Input.ArticleContent;
                    result.CategoryId = Input.CategoryId;
                    result.Author = Input.Author;
                    result.CommentEndDate = Input.CommentEndDate;
                    result.CommentStartDate = Input.CommentStartDate;
                    result.ImageUrl = Input.ImageUrl;
                    result.Keyword = Input.Keyword;
                    result.ShortTitle = Input.ShortTitle;
                    result.Source = Input.Source;
                    result.Title = Input.Title;
                    result.Enabled = Input.Enabled;
                    result.CreateTime = DateTime.Now;
                    result.UpdateTime = DateTime.Now;
                    result.OrderIndex = Input.OrderIndex;
                    result.CreateBy = _applicationUser.UserId;
                    result.UpdateBy = _applicationUser.UserId;
                    await _newsRepository.InsertAsync(result);
                }
                else
                {
                    result.CategoryId = Input.CategoryId;
                    result.AllowComment = Input.AllowComment;
                    result.ArticleAbstract = Input.ArticleAbstract;
                    result.ArticleContent = Input.ArticleContent;
                    result.Author = Input.Author;
                    result.CommentEndDate = Input.CommentEndDate;
                    result.CommentStartDate = Input.CommentStartDate;
                    result.ImageUrl = Input.ImageUrl;
                    result.Keyword = Input.Keyword;
                    result.ShortTitle = Input.ShortTitle;
                    result.Source = Input.Source;
                    result.Title = Input.Title;
                    result.Enabled = Input.Enabled;
                    result.UpdateTime = DateTime.Now;
                    result.OrderIndex = Input.OrderIndex;
                    result.UpdateBy = _applicationUser.UserId;
                    await _newsRepository.UpdateAsync(result);
                }
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("保存成功!");
            }
            catch (Exception ex)
            {
                _logger.LogError("保存资讯异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 设置资讯是否可用
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SetNewsEnabled(int id, bool enabled)
        {
            try
            {

                var news = await _newsRepository.GetFirstOrDefaultAsync(x => x.Id == id);
                if (news == null) return null;
                news.Enabled = enabled;
                await _newsRepository.UpdateAsync(news);
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("设置成功!");

            }
            catch (Exception ex)
            {
                _logger.LogError("设置资讯是否可用异常", ex);
                throw;
            }
        }
        #endregion






    }
}
